<%@ Page Language="C#" %>
<%@ Import namespace="SubSonic.Utilities"%>
<%@ Import Namespace="SubSonic" %>
<%
    //The data we need
	string providerName = "#PROVIDER#";
	string tableName = "#TABLE#";
	TableSchema.Table tbl = DataService.GetSchema(tableName, providerName, TableType.Table);
	DataProvider provider = DataService.Providers[providerName];
    ICodeLanguage lang = new CSharpCodeLanguage();
    
    //The main vars we need
    TableSchema.TableColumnCollection cols = tbl.Columns;
    TableSchema.TableColumn[] keys = cols.GetPrimaryKeys();
    bool showGenerationInfo = false;
    bool useNullables = tbl.Provider.GenerateNullableProperties;
    string className = tbl.ClassName;
    string thisPK = tbl.PrimaryKey.PropertyName;
    string varPK = tbl.PrimaryKey.ArgumentName;
    string varPKType = Utility.GetVariableType(tbl.PrimaryKey.DataType, tbl.PrimaryKey.IsNullable, lang);

%>

<% if(showGenerationInfo)
   { %>
 //Generated on <%=DateTime.Now.ToString() %> by <%=Environment.UserName %>
<% }  %>
namespace <%=provider.GeneratedNamespace %>
{
    /// <summary>
    /// Controller class for <%=tbl.Name %>
    /// </summary>
    [System.ComponentModel.DataObject]
    [SubSonic.Remoting.RemoteDataController]
    public partial class <%=tbl.ClassName %>Controller:ActiveController[<]<%=tbl.ClassName %>,<%=tbl.ClassName %>Collection[>]
    {
        #region "Singleton"        
        private static <%=tbl.ClassName %>Controller _instanceController = null;
        public static <%=tbl.ClassName %>Controller RemoteInstance
        {
            get
            {
                if (_instanceController == null)
                {
                    lock (LockController)
                    {
                        if (_instanceController == null)
                            _instanceController = new <%=tbl.ClassName %>Controller();
                    }
                }
                return _instanceController;
            }
        }
        #endregion
        
        #region "Remoting"
        
        [SubSonic.Remoting.RemoteServerRegistrationMethod(System.Runtime.Remoting.WellKnownObjectMode.SingleCall)]
        public static void RegisterRemoteServer(System.Runtime.Remoting.WellKnownObjectMode callingMode)
        {
            System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(<%=provider.GeneratedNamespace %>.<%=tbl.ClassName %>Controller), 
                "<%=provider.GeneratedNamespace.Replace(".","_") %>_<%=tbl.ClassName %>Controller.rem", 
                callingMode);
        }

        [SubSonic.Remoting.RemoteClientRegistrationMethod]
        public static void RegisterRemoteClient(string host, int port)
        {
            System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownClientType(
                    typeof(<%=provider.GeneratedNamespace %>.<%=tbl.ClassName %>Controller),
                    Utility.FormatRemoteUrl(host, port, "<%=provider.GeneratedNamespace.Replace(".","_") %>_<%=tbl.ClassName %>Controller.rem"));
        }
        
        #endregion
                
        // Preload our schema..
        <%=tbl.ClassName%> thisSchemaLoad = new <%=tbl.ClassName%>();

        private string userName = string.Empty;
        protected string UserName
        {
            get
            {
				if (userName.Length == 0) 
				{
    				if (System.Web.HttpContext.Current != null)
    				{
						userName=System.Web.HttpContext.Current.User.Identity.Name;
					}
					else
					{
						userName=System.Threading.Thread.CurrentPrincipal.Identity.Name;
					}
				}
				return userName;
            }
        }

    	<%
			string insertArgs = string.Empty;
			string updateArgs = string.Empty;
			string seperator = ",";

			foreach (TableSchema.TableColumn col in cols)
			{
				string propName = col.PropertyName;
				bool useNullType = useNullables ? col.IsNullable : false;
				string varType = Utility.GetVariableType(col.DataType, useNullType, lang);

				updateArgs += varType + " " + propName + seperator;
				if (!col.AutoIncrement)
				{
					insertArgs += varType + " " + propName + seperator;
				}
			}
			/*
			if (insertArgs.Length > 0)
				insertArgs = insertArgs.Remove(insertArgs.Length - seperator.Length, seperator.Length);
			if (updateArgs.Length > 0)
				updateArgs = updateArgs.Remove(updateArgs.Length - seperator.Length, seperator.Length);
			*/
        %>
    	
	    /// <summary>
	    /// Inserts a record, can be used with the Object Data Source
	    /// </summary>
        [DataObjectMethod(DataObjectMethodType.Insert, true)]
	    public void Insert(<%=insertArgs%> string userName)
	    {
		    <%=tbl.ClassName %> item = new <%= tbl.ClassName %>();
		    <% 
		    foreach (TableSchema.TableColumn col in cols) {
                if (!col.AutoIncrement) { 
            %>
            item.<%=col.PropertyName%> = <%=col.PropertyName%>;
            <%
                }
              } 
            %>
	    
		    Save(item,userName);
	    }

    	
	    /// <summary>
	    /// Updates a record, can be used with the Object Data Source
	    /// </summary>
        [DataObjectMethod(DataObjectMethodType.Update, true)]
	    public void Update(<%=updateArgs%> string userName)
	    {
		    <%=tbl.ClassName%> item = new <%=tbl.ClassName %>();
		    <% 
		    foreach (TableSchema.TableColumn col in cols) 
			{
				%>
				item.<%=col.PropertyName%> = <%=col.PropertyName%>;
				<%
			} 
            %>
		    item.MarkOld();
		    Save(item,userName);
	    }
	    
	    
	    

		
		<%if (tbl.ManyToManys.Count > 0) { %>
		#region Many To Many Helpers
		<%
			TableSchema.ManyToManyRelationshipCollection mm = tbl.ManyToManys;
			if (mm != null)
			{
				ArrayList usedConstraints = new ArrayList();
				foreach (TableSchema.ManyToManyRelationship m in mm)
				{
					TableSchema.Table fkSchema = DataService.GetSchema(m.ForeignTableName, providerName, TableType.Table);
					if (fkSchema != null && !usedConstraints.Contains(fkSchema.ClassName) && CodeService.ShouldGenerate(fkSchema) && CodeService.ShouldGenerate(m.MapTableName, m.Provider.Name))
					{
						usedConstraints.Add(fkSchema.ClassName);
						string fkClass = fkSchema.ClassName;
						string fkClassQualified = provider.GeneratedNamespace + "." + fkClass;
				
		%>
		 
		public <%=fkClassQualified%>Collection Get<%=fkClass%>Collection(<%= varPKType%> <%= varPK%>)
		{
			SubSonic.QueryCommand cmd = new SubSonic.QueryCommand(
				"SELECT * FROM <%=m.ForeignTableName%> INNER JOIN <%=m.MapTableName%> ON "+
				"<%=m.ForeignTableName%>.<%=m.ForeignPrimaryKey%>=<%=m.MapTableName%>.<%=m.MapTableForeignTableKeyColumn%> WHERE <%=m.MapTableName%>.<%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name);
			
			cmd.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>, DbType.<%= DataService.GetSchema(m.MapTableName, providerName).GetColumn(m.MapTableLocalTableKeyColumn).DataType.ToString() %>);
			IDataReader rdr = SubSonic.DataService.GetReader(cmd);
			<%=fkClass%>Collection coll = <%=fkClass%>Controller.RemoteInstance.List(rdr);
			return coll;
		}
		
		public void Save<%=fkClass%>Map(<%= varPKType%> <%= varPK%>, <%=fkClass%>Collection items, string userName)
		{
			QueryCommandCollection coll = new SubSonic.QueryCommandCollection();

			//delete out the existing
			QueryCommand cmdDel = new QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name);
			cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
			coll.Add(cmdDel);
			DataService.ExecuteTransaction(coll);
			foreach (<%=fkClass%> item in items)
			{
				<%=m.ClassName%> var<%=m.ClassName%> = new <%= m.ClassName%>();
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", item.GetPrimaryKeyValue());
				<%=m.ClassName%>Controller.RemoteInstance.Save(var<%=m.ClassName%>,userName);
			}
		}

		public void Save<%=fkClass%>Map(<%= varPKType%> <%= varPK%>, System.Web.UI.WebControls.ListItemCollection itemList, string userName) 
		{
			QueryCommandCollection coll = new SubSonic.QueryCommandCollection();

			//delete out the existing
			 QueryCommand cmdDel = new QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name);
			cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
			coll.Add(cmdDel);
			DataService.ExecuteTransaction(coll);

			foreach (System.Web.UI.WebControls.ListItem l in itemList) 
			{
				if (l.Selected) 
				{
					<%=m.ClassName%> var<%=m.ClassName%> = new <%= m.ClassName%>();
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
					var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", l.Value);
					<%=m.ClassName%>Controller.RemoteInstance.Save(var<%=m.ClassName%>,userName);
				}
			}
		}

		public void Save<%=fkClass%>Map(<%= varPKType%> <%= varPK%> , <%= varPKType%>[] itemList, string userName) 
		{
			QueryCommandCollection coll = new SubSonic.QueryCommandCollection();

			//delete out the existing
			 QueryCommand cmdDel = new QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name);
			cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
			coll.Add(cmdDel);
			DataService.ExecuteTransaction(coll);

			foreach (<%= varPKType%> item in itemList) 
			{
				<%=m.ClassName%> var<%=m.ClassName%> = new <%= m.ClassName%>();
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
				var<%=m.ClassName%>.SetColumnValue("<%=m.MapTableForeignTableKeyColumn%>", item);
				<%=m.ClassName%>Controller.RemoteInstance.Save(var<%=m.ClassName%>,userName);
			}
		}
		
		public void Delete<%=fkClass%>Map(<%= varPKType%> <%= varPK%>) 
		{
			QueryCommand cmdDel = new QueryCommand("DELETE FROM <%=m.MapTableName%> WHERE <%=m.MapTableLocalTableKeyColumn%>=@<%=m.MapTableLocalTableKeyColumn%>", <%=className%>.Schema.Provider.Name);
			cmdDel.AddParameter("@<%=m.MapTableLocalTableKeyColumn%>", <%= varPK%>);
			DataService.ExecuteQuery(cmdDel);
		}

		<%
			}
		}
	}
		%>
		#endregion
		<%} else {%>
		//no ManyToMany tables defined (<%=tbl.ManyToManys.Count.ToString() %>)
		<%} %>
	    
	    
	    
	    

    }

}
